from datetime import datetime
from flask import current_app
from flask import request
from flask_restful import Resource
from models.user import User
from toutiao.apps.user.constants import SMS_VERIFICATION_CODE_EXPIRES
from flask_restful.reqparse import RequestParser
from toutiao import db
from flask import g

class LoginResource(Resource):
    """
    用户登陆注册
    """
    def post(self):
        # 1.接收数据, 验证数据
        # 1.1 创建验证实例
        parser = RequestParser()
        # 1.2 添加验证参数
        from flask_restful import inputs
        from toutiao.utils.parsers import check_mobile
        # 通过正则来验证
        # parser.add_argument("mobile",location="json",required=True,type=inputs.regex("1[3-9]\d{9}"))
        # 定义一个函数验证
        parser.add_argument('mobile',location='json',required=True,type=check_mobile)
        parser.add_argument('code',location='json',required=True,type=inputs.regex('\d{6}'))
        # 1.3 验证并获取验证之后的数据
        args = parser.parse_args()
        # 1.4 获取数据
        mobile = args.get("mobile")
        code = args.get("code")

        # 2.验证短信验证码
        redis_code = current_app.redis_store.get("app_code:{}".format(mobile))
        if redis_code is None or redis_code.decode() != code:
            return {"message":"短信验证码错误"},400
        # 3.根据手机号查询判断用户是否注册
        # 进行异常捕获保证程序的健壮性
        user = None
        try:
            user = User.query.filter_by(mobile=mobile).first()
        except Exception as e:
            current_app.logger.error(e)
        if user:
            # 4.如果注册过
            user.last_login = datetime.now()
            try:
                db.session.commit()
            except Exception as e:
                current_app.logger.error(e)

        else:
            # 5.如果没有注册过,就保存手机号同事生成记录,
            user_id = current_app.id_worker.get_id()
            user = User()
            user.id = user_id
            user.mobile = mobile
            user.name = mobile
            user.last_login = datetime.now()
        try:
            db.session.add(user)
            db.session.commit()
        except Exception as e:
            current_app.logger.error(e)
            # 507 存储问题
            return {"message":"database error"},507

        # 6.生成一个token
        from toutiao.utils.token import get_user_token
        token,refresh_token = get_user_token(user.id)

        # 缓存用户信息:缓存id,头像,name
        from cache.user import UserProfileCache,UserStatusCache
        #　用户信息缓存
        UserProfileCache(user.id).save()
        # 用户状态缓存
        UserStatusCache(user.id).save(user.status)

        if not user.status:
            return {"message":"用户不允许登陆,请重试..."},403

        # 7.返回响应
        return {"token":token,
                "refresh_token":refresh_token}


    def put(self):
        """
        根据refresh_token换取token
        :return:
        """
        # 1. user_id 和refresh都有才正确
        if all([g.user_id,g.is_refresh_token]):
            # 2. 先判断下用户状态
            from cache.user import UserStatusCache
            if not UserStatusCache(g.user_id).get():
                return {"message":"请登录"},403

            # 3. 正确的话就生成token
            from toutiao.utils.token import get_user_token
            token,refresh_token = get_user_token(g.user_id)
            return {"token":token}

        else:
            # 4. user_id 和refresh 有一个不正确,就返回403
            return {"message":"请重新登陆"},403



class SmsCodeResourece(Resource):
    """
    获取短信验证码
    """
    def get(self,mobile):
        # 1. 获取手机号,路由中已经获取到了
        # 2. 生成短信验证码
        from random import choice
        from string import digits
        # 导入choice和digits
        # 表示随机获取digits(0-9)中的数据
        # 拼接拿到的随机生成的6位数值
        code = "".join([choice(digits) for _ in range(6)])

        # 3. 保存到Redis
        # current_app.redis_store.setex(key,expires,value)
        current_app.redis_store.setex("app_code:{}".format(mobile),SMS_VERIFICATION_CODE_EXPIRES,code)

        # 日志输出短信验证码:方便查看,不用查看Redis了
        current_app.logger.info(code)
        # 4. 返回响应
        return {
            'mobile':mobile
        }


#查询数据
from toutiao.utils.decorators import loginrequired

class UserInfoResource(Resource):

    # 添加装饰器
    method_decorators = [loginrequired]

    def get(self):
        # user = User.query.filter_by(id=1).first()
        #
        # user_data = {
        #     'id': user.id,
        #     'mobile': user.mobile,
        #     'name': user.name,
        #     'photo': user.profile_photo or '',
        #     'is_media': user.is_media,
        #     'intro': user.introduction or '',
        #     'certi': user.certificate or '',
        # }
        #
        # return user_data
        # user_id 先写死,方便测试
        from cache.user import UserProfileCache
        # user_id = 1
        user_id = g.user_id
        user_data = UserProfileCache(user_id).get()
        return user_data



import json
#查询redis缓存
class CacheUserInfoResource(Resource):

    def get(self):
        redis_data=current_app.redis_store.get(1)
        user_data=json.loads(redis_data.decode())
        return user_data
    #用户第一次将数据库中的数据保存到缓存
    def post(self):
        user = User.query.filter_by(id=1).first()

        user_data = {
            'id': user.id,
            'mobile': user.mobile,
            'name': user.name,
            'photo': user.profile_photo or '',
            'is_media': user.is_media,
            'intro': user.introduction or '',
            'certi': user.certificate or '',
        }

        current_app.redis_store.set(1, json.dumps(user_data))

        return {'message':'ok'}
